import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

/**
 * 
 * Authors - Oren Bracha, Rony Lahav & Yehuda Eterman
 *
 * used to print log data into output.txt file
 */
public class Logger {
	private static Logger logger = null;
	static PrintWriter pw; 
	
	//opens output file
	private Logger() throws IOException{
		pw = new PrintWriter(new FileWriter(proj350.outputFilePath));
	}
	
	//singleton
	public static Logger getInstance()
	{
		try {
			if (logger == null) {
				logger = new Logger();
			}
		}
		catch(IOException e) {
		}
		return logger;
	}
	
	//for debugging - printed free text 
	public synchronized void printFreeText(String message){
		pw.println("time:" + DateStringConverter.timeCurrentForLogger());
		pw.println(message);
		pw.println();
		pw.flush();
	}
	
	//print a command data
	public synchronized void printCommandDetails(String command, String parameters){
		pw.println("time:" + DateStringConverter.timeCurrentForLogger());
		pw.println("command:"+command+parameters);
		pw.println();
		pw.flush();
	}
	
	//prints a WRONG FORMAT message including the FROM and TO data
	public synchronized HashMap<String,String> printErrorWrongFormat(String messageType, String content, String from, String ipFrom, String portFrom, String to, String ipTo, String portTo, String conType) {
		StringBuilder sb = new StringBuilder();
		sb.append("time:" + DateStringConverter.timeCurrentForLogger() + MessageCenter.newline);
		sb.append("error:wrong format in " + messageType + " message" + MessageCenter.newline);
		sb.append("content:" + content + MessageCenter.newline);
		if (from == null)
			sb.append("from:unknown" + MessageCenter.newline);
		else
			sb.append("from:" + from + MessageCenter.newline);
		if (ipFrom == null)
			sb.append("ip:unknown" + MessageCenter.newline);
		else
			sb.append("ip:" + ipFrom + MessageCenter.newline);
		if (portFrom == null)
			sb.append(conType + ":unknown" + MessageCenter.newline);
		else
			sb.append(conType + ":" +portFrom + MessageCenter.newline);
		sb.append("to:" + to + MessageCenter.newline);
		sb.append("ip:" + ipTo + MessageCenter.newline);
		sb.append(conType+ ":" + portTo + MessageCenter.newline);
		pw.println(sb);
		pw.flush();
		return null;
	}

	//prints a NOT AVAILABLE message 
	public synchronized void printErrorNotAvailable(String peerName) {
		StringBuilder sb = new StringBuilder();
		sb.append("time:" + DateStringConverter.timeCurrentForLogger() + MessageCenter.newline);
		sb.append("peer " + peerName + " not available" + MessageCenter.newline);
		pw.println(sb);
		pw.flush();
	}
	
	//prints an OUTGOING or INCOMING message including the FROM and TO data
	public synchronized HashMap<String,String> printInOutMsg(boolean in, String message, String from, String ipFrom, String portFrom, String to, String ipTo, String portTo, String conType) {
		StringBuilder sb = new StringBuilder();
		sb.append("time:" + DateStringConverter.timeCurrentForLogger() + MessageCenter.newline);
		if (in)
		{
			sb.append("inmsg:" + message + MessageCenter.newline);
		}
		else
		{
			sb.append("outmsg:" + message + MessageCenter.newline);
		}
		if (from == null){
			String fromName = "unknown";
			if(message.startsWith(MessageCenter.TYPE_UPDATE))
				fromName = message.split(MessageCenter.VAR_PEERNAME + "=")[1].split(">")[0];
			sb.append("from:" + fromName + MessageCenter.newline);
		}
		else
			sb.append("from:" + from + MessageCenter.newline);
		if (ipFrom == null)
			sb.append("ip:unknown" + MessageCenter.newline);
		else
			sb.append("ip:" + ipFrom + MessageCenter.newline);
		if (portFrom == null)
			sb.append(conType + ":unknown" + MessageCenter.newline);
		else
			sb.append(conType + ":" + portFrom + MessageCenter.newline);
		sb.append("to:" + to + MessageCenter.newline);
		sb.append("ip:" + ipTo + MessageCenter.newline);
		sb.append(conType + ":" + portTo + MessageCenter.newline);
		pw.println(sb);
		pw.flush();
		return null;
	}
	
	public void close(){
		pw.close();
	}
	
}
